Skip to content

GH4890: Add typed Cake aliases for dotnet tool subcommands#4846

Merged
devlead merged 1 commit into
cake-build:developfrom
paulomorgado:feature/implement-dotnet-tool-commands
Jun 12, 2026
Merged

GH4890: Add typed Cake aliases for dotnet tool subcommands#4846
devlead merged 1 commit into
cake-build:developfrom
paulomorgado:feature/implement-dotnet-tool-commands

Conversation

@paulomorgado

Copy link
Copy Markdown
Contributor

Summary

Adds first-class Cake aliases for the dotnet tool command family, covering the requested subcommands from discussion #4843:

  • DotNetToolExecute
  • DotNetToolInstall
  • DotNetToolList
  • DotNetToolRestore
  • DotNetToolRun
  • DotNetToolSearch
  • DotNetToolUninstall
  • DotNetToolUpdate

Details

This introduces command-specific settings types for each supported dotnet tool subcommand, matching the existing DotNet alias style in Cake instead of using a generic shared settings/arguments shape.

Forwarded tool arguments are only supported where the underlying CLI executes a tool:

  • DotNetToolExecute(..., ProcessArgumentBuilder arguments, ...)
  • DotNetToolRun(..., ProcessArgumentBuilder arguments, ...)

Those forwarded arguments are kept out of the settings classes and are appended after --, consistent with existing aliases like DotNetRun and DotNetTest.

The aliases also include XML documentation links to the corresponding Microsoft dotnet tool command documentation.

Testing

Added unit coverage for:

  • all new alias overloads
  • command-specific settings rendering
  • forwarded tool arguments for execute/run
  • required argument validation
  • working directory behavior from project paths
  • process start and non-zero exit failure handling
  • argument customization preservation

@devlead devlead left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address code compilation issues, first after that this will be reviewed.

@paulomorgado paulomorgado force-pushed the feature/implement-dotnet-tool-commands branch 2 times, most recently from 22fd64d to e68c3a7 Compare June 2, 2026 15:22
@paulomorgado

Copy link
Copy Markdown
Contributor Author

Please address code compilation issues, first after that this will be reviewed.

OOPS!

Fixed!

@devlead devlead left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--verbosity is emitted for subcommands that do not support it

Thanks for the thorough coverage here, the alias shape, settings types, and tests all look consistent with the rest of our DotNet tooling.

One concern I'd like addressed before merge: all of the new settings types inherit DotNetSettings.Verbosity, and because these aliases route through DotNetToolRunner, --verbosity is always appended via AppendCommonArguments.
That works for some dotnet tool subcommands, but not all of them.

I verified this against the CLI locally:

  • Supported: install, update, exec, restore
  • Not supported: run, list, search, uninstall
    For example, dotnet tool run --verbosity minimal fails at runtime because --verbosity is treated as the tool command name.

The unit tests currently assert argument strings that include --verbosity for unsupported commands as well (for example, RunFull, ListFull, SearchFull, and UninstallFull). Those tests pass because they only verify rendered arguments, not actual CLI behavior, so this regression would not be caught in CI.
Impact: If a user sets Verbosity on DotNetToolRunSettings, DotNetToolListSettings, DotNetToolSearchSettings, or DotNetToolUninstallSettings, the resulting command will fail when executed.
Suggestion: Please either:

  1. Only append --verbosity for subcommands that support it, or
  2. Use per-command runners/argument builders (similar to the workload commands),

Minor notes

A few smaller things I noticed:
No integration tests
Other DotNet aliases have coverage under tests/integration/Cake.Common/Tools/DotNet/. The unit tests here are thorough, but a lightweight integration test (even just install + list + uninstall against a manifest) would give extra confidence that the rendered commands work end-to-end.

Different architecture than workload commands
Workload subcommands use dedicated runners per command; this PR centralizes through DotNetTool. That's a reasonable trade-off for less duplication, just noting the pattern difference in case we want consistency long-term.

Temporary mutation of settings.ArgumentCustomization
RunDotNetToolCommandWithForwardedArguments temporarily replaces ArgumentCustomization and restores it in finally. That's tested for DotNetToolExecute but not for DotNetToolRun. Unlikely to matter in practice, but reusing the same settings instance across parallel tasks could theoretically race.

Large file
src/Cake.Common/Tools/DotNet/DotNetAliases.ToolCommands.cs is quite large; it would be better if each sub-command was in its own file.

@paulomorgado paulomorgado force-pushed the feature/implement-dotnet-tool-commands branch 2 times, most recently from 9bb4b9c to da92706 Compare June 8, 2026 09:09
@paulomorgado

Copy link
Copy Markdown
Contributor Author

--verbosity on unsupported subcommands

run, list, search, and uninstall now go through no-verbosity wrappers (RunDotNetToolCommandWithoutVerbosity / RunDotNetToolCommandWithForwardedArgumentsWithoutVerbosity in DotNetAliases.Tool.Common.cs), so Verbosity is not emitted for commands that don’t support it.
I also updated unit-test expectations (DotNetToolCommandTests) to remove --verbosity for those cases.

Missing ArgumentCustomization restoration test for run

Added DotNetToolRun_WithArgumentCustomization_RestoresOriginalCustomization in DotNetToolCommandTests.cs, mirroring the existing execute-path coverage.

Large file concern

Split DotNetAliases.ToolCommands.cs into command-focused files (DotNetAliases.Tool.{Execute,Install,List,Restore,Run,Search,Uninstall,Update}.cs) plus shared helpers in DotNetAliases.Tool.Common.cs.

No integration test coverage

Added Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListUninstallLocal in tests/integration/Cake.Common/Tools/DotNet/DotNetAliases.cake to exercise local install -> list -> uninstall against a manifest, and wired it into the DotNet integration dependency chain.

I'm having issues testing this, though.

How can I test this locally?

Can you help, @devlead?

@devlead

devlead commented Jun 8, 2026

Copy link
Copy Markdown
Member

@paulomorgado integration tests can be tested locally by calling main cake script in repo root like this

dotnet cake --target="Run-Integration-Tests"

You can test just a specific integration test target with increased verbosity like below

dotnet cake --target="Run-Integration-Tests" --integration-tests-target="Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListUninstallLocal" --integration-tests-verbosity=Diagnostic

If you got en error in the integration test script, then you can execute tests without needed rebuild and execute unit tests by passing the --exclusive flag.

dotnet cake --target="Run-Integration-Tests" --integration-tests-target="Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListUninstallLocal" --integration-tests-verbosity=Diagnostic --exclusive

@paulomorgado

Copy link
Copy Markdown
Contributor Author

@devlead,

There must be something not compatible in my local environment.

I tried

dotnet cake --target="Run-Integration-Tests"

but it failed on Run-Unit-Tests because I don't have .NET 9.0 installed.

Then I tried

dotnet cake --target="Run-Integration-Tests" --integration-tests-target="Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListUninstallLocal" --integration-tests-verbosity=Diagnostic --exclusive

and got

Tool GitVersion.Tool is already installed, with required version.
Tool GitReleaseManager.Tool is already installed, with required version.

────────────────────────────────────────────────────────────────────────────────────────────────────
 Setup
────────────────────────────────────────────────────────────────────────────────────────────────────
Calculating Semantic Version
Calculated Semantic Version: 6.3.0-implement-dotnet-tool-commands0001 (Version: 6.3.0, Milestone: v6.3.0)
Building version 6.3.0-implement-dotnet-tool-commands0001 of Cake (Release, Run-Integration-Tests) using version 6.2.0.0 of Cake.
        (IsTagged: False, IsMainCakeRepo: False, IsMainCakeBranch: False, IsDevelopCakeBranch: False)
        (ShouldPublish: False, ShouldPublishToAzureDevOps: False, ShouldSignPackages: False, IsPullRequest: False)

════════════════════════════════════════════════════════════════════════════════════════════════════
 Run-Integration-Tests
════════════════════════════════════════════════════════════════════════════════════════════════════
An error occurred when executing task 'Run-Integration-Tests'.

────────────────────────────────────────────────────────────────────────────────────────────────────
 TearDown
────────────────────────────────────────────────────────────────────────────────────────────────────
Starting Teardown...
Finished running tasks.

  Task                                             Duration                        Status
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Setup                                            00:00:01.4025347                Succeeded
  Run-Integration-Tests                            00:00:00.0110450                Succeeded
  Teardown                                         00:00:00.0017085                Succeeded
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Total:                                           00:00:01.4152882

Error: Sequence contains no elements

The same happens with Cake.Common.Tools.DotNet.DotNetAliases.DotNetTool.

@devlead

devlead commented Jun 8, 2026

Copy link
Copy Markdown
Member

--exclusive is only if you already built Cake and prepared for integration test once and want to test integration tests without rebuilding and executing tests each time.

Cake targets .NET 8, 9, and 10, both unit tests and integration tests are executed on them, you can install .NET SDKs locally just in repo by executing the PowerShell bootstrapper

$env:CAKE_INSTALL_SUPPORTED_SDKS='true'
.\build.ps1 --target="Run-Integration-Tests" --integration-tests-target="Cake.Common.Tools.DotNet.DotNetAliases.DotNetTool" --integration-tests-verbosity=Diagnostic

@paulomorgado

Copy link
Copy Markdown
Contributor Author

@devlead, because the integration test is registering a local dotnet tool, this should be on an empty directory.

What's the best strategy to do that in the integration test?

@paulomorgado paulomorgado force-pushed the feature/implement-dotnet-tool-commands branch from da92706 to f146fb4 Compare June 8, 2026 17:21
@paulomorgado

Copy link
Copy Markdown
Contributor Author

@devlead,

I was able to run the Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListRunUninstallLocal integration test locally, but Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolExecute only succeeded for the first target SDK.

What am I doing wrong?

@paulomorgado paulomorgado force-pushed the feature/implement-dotnet-tool-commands branch from f146fb4 to 5633ef2 Compare June 8, 2026 22:52
@devlead

devlead commented Jun 11, 2026

Copy link
Copy Markdown
Member

@devlead, because the integration test is registering a local dotnet tool, this should be on an empty directory.

What's the best strategy to do that in the integration test?

Run-Integration-Tests runs the same integration target three times, once per Cake.dll built (net8.0, net9.0, net10.0).

For empty / work folder Paths.Temp + subfolder is the pattern. Which you already seem to partially do, i.e. var workingDirectory = Paths.Temp.Combine("./Cake.Common/Tools/DotNet");

Shared working directory, DotNetToolExecute and DotNetToolInstallListRunUninstallLocal share ./Cake.Common/Tools/DotNet; when run as part of the full DotNetAliases suite, they are sibling dependencies of DotNetBuildServerShutdown and may interact. Run the execute test in isolation to confirm:

dotnet cake --target="Run-Integration-Tests" `
  --integration-tests-target="Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolExecute" `
  --integration-tests-verbosity=Diagnostic

Paths.Temp is cleared as part of the integration tests setup. If you need test isolation, each test should have it's own subfolder

I.e.

- var workingDirectory = Paths.Temp.Combine("./Cake.Common/Tools/DotNet");
+ var workingDirectory = Paths.Temp.Combine("./Cake.Common/Tools/DotNet/DotNetToolInstallListRunUninstallLocal");

Would ensure a dedicated folder for just that test,

@paulomorgado

Copy link
Copy Markdown
Contributor Author

@devlead, both Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolExecute and Cake.Common.Tools.DotNet.DotNetAliases.DotNetToolInstallListRunUninstallLocal are successfully running now.

@augustoproiete augustoproiete linked an issue Jun 11, 2026 that may be closed by this pull request
@augustoproiete augustoproiete changed the title Add typed Cake aliases for dotnet tool subcommands GH4890: Add typed Cake aliases for dotnet tool subcommands Jun 11, 2026
@devlead devlead force-pushed the feature/implement-dotnet-tool-commands branch 2 times, most recently from c1a19d5 to dc71ec1 Compare June 11, 2026 21:39
Add typed aliases and settings for dotnet tool subcommands, including install, list, restore, run, search, uninstall, update, and execute. Model command-specific options with dedicated settings classes, keep forwarded tool arguments as explicit ProcessArgumentBuilder parameters for execute/run, and add docs links for each alias.

Add unit coverage for command rendering, overloads, settings, forwarded arguments, validation, working directory behavior, and failure handling.
@devlead devlead force-pushed the feature/implement-dotnet-tool-commands branch from c4f861c to bc746f7 Compare June 12, 2026 05:47

@devlead devlead left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@devlead devlead merged commit ddc3fce into cake-build:develop Jun 12, 2026
17 of 18 checks passed
@devlead

devlead commented Jun 12, 2026

Copy link
Copy Markdown
Member

@paulomorgado your changes have been merged, thanks for your contribution 👍

@paulomorgado paulomorgado deleted the feature/implement-dotnet-tool-commands branch June 12, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add typed Cake aliases for dotnet tool subcommands

2 participants